import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:kq_flutter_core_widget/utils/toast_util.dart';

/// 文件选择工具
///
/// 包括图片或文件选择
/// 其中文件选择仅支持Android端，iOS只支持选择图片
class FilePickerNativeUtil {
  static const _methodChannelName = 'flutter.keqiang.com/filePicker';

  static const _platformMethod = MethodChannel(_methodChannelName);

  /// 拍照
  /// [compress]指定图片压缩后的大小，[compress]为null或[compress]<=0时不压缩，图片本身大小 <= [compress]时也不压缩，单位KB
  static Future<KqFile?> takePhoto({int? compress}) async {
    try {
      var result = await _platformMethod
          .invokeMethod('takePhoto', {'compress': compress});
      if (result['code'] == 1) {
        dynamic e = result['data'];
        return KqFile(
            fileName: e['fileName'],
            filePath: e['filePath'],
            fileLength: e['fileLength'],
            mime: e['mime'],
            suffix: e['suffix']);
      } else if (result['code'] == 0) {
        var msg = result['msg'];
        KqToast.showNormal(msg);
      }
      return null;
    } on PlatformException catch (e) {
      debugPrint(e.message);
      return null;
    }
  }

  /// 选择图片
  /// [compress]指定图片压缩后的大小，[compress]为null或[compress]<=0时不压缩，图片本身大小 <= [compress]时也不压缩，单位KB
  static Future<List<KqFile>> pickImages(
      {int maxCount = 1, int? compress}) async {
    try {
      var result = await _platformMethod.invokeMethod(
          'pickImages', {'maxCount': maxCount, 'compress': compress});
      if (result['code'] == 1) {
        List<dynamic> data = result['data'];
        return data
            .map((e) => KqFile(
                fileName: e['fileName'],
                filePath: e['filePath'],
                fileLength: e['fileLength'],
                mime: e['mime'],
                suffix: e['suffix']))
            .toList();
      } else if (result['code'] == 0) {
        var msg = result['msg'];
        KqToast.showNormal(msg);
      }
      return [];
    } on PlatformException catch (e) {
      debugPrint(e.message);
      return [];
    }
  }

  /// 选择文件时，指定多语言文本资源
  static StringRes? stringRes;

  /// 选择指定类型文件
  ///
  /// [extensions]为文件后缀，指定哪些类型文件可选，不传或空列表则表示所有文件可选
  /// [compress]指定图片压缩后的大小，[compress]为null或[compress]<=0时不压缩，图片本身大小 <= [compress]时也不压缩，
  /// 如果选择的文件非图片也不压缩，单位KB
  static Future<List<KqFile>> pickFiles(
      {List<String>? extensions, int maxCount = 1, int? compress}) async {
    try {
      var result = await _platformMethod.invokeMethod('pickFiles', {
        'maxCount': maxCount,
        'extensions': extensions,
        'compress': compress,
        'stringRes': stringRes == null ? null : json.encode(stringRes)
      });
      if (result['code'] == 1) {
        List<dynamic> data = result['data'];
        return data
            .map((e) => KqFile(
                fileName: e['fileName'],
                filePath: e['filePath'],
                fileLength: e['fileLength'],
                mime: e['mime'],
                suffix: e['suffix']))
            .toList();
      } else if (result['code'] == 0) {
        var msg = result['msg'];
        KqToast.showNormal(msg);
      }
      return [];
    } on PlatformException catch (e) {
      debugPrint(e.message);
      return [];
    }
  }
}

/// 文件选择结果
class KqFile {
  const KqFile(
      {this.fileName, this.filePath, this.fileLength, this.suffix, this.mime});

  /// 文件名
  final String? fileName;

  /// 文件路径
  final String? filePath;

  /// 文件大小
  final int? fileLength;

  /// 文件后缀
  final String? suffix;

  /// MIME
  final String? mime;

  @override
  String toString() {
    return '''{"fileName"": "$fileName","filePath": "$filePath","suffix": "$suffix","fileLength": $fileLength,"mime": "$mime"}''';
  }
}

/// 常用文件的扩展名
enum Extension {
  txt('txt', MIME.txt),
  html('html', MIME.html),
  csv('csv', MIME.csv),
  json('json', MIME.json),
  jpeg('jpeg', MIME.jpeg),
  jpg('jpg', MIME.jpeg),
  png('png', MIME.png),
  gif('gif', MIME.gif),
  webp('webp', MIME.webp),
  pdf('pdf', MIME.pdf),
  zip('zip', MIME.zip),
  rar('rar', MIME.rar),
  jar('jar', MIME.jar),
  xls('xls', MIME.xls),
  xlsx('xlsx', MIME.xlsx),
  doc('doc', MIME.doc),
  docx('docx', MIME.docx),
  ppt('ppt', MIME.ppt),
  pptx('pptx', MIME.pptx),
  mp3('mp3', MIME.mp3),
  wav('wav', MIME.wav),
  mp4('mp4', MIME.mp4),
  apk('apk', MIME.apk);

  const Extension(this.name, this.mime);

  final String name;
  final String mime;
}

/// 常用文件类型的MIME
class MIME {
  /// .txt
  static const String txt = "text/plain";

  /// .html
  static const String html = "text/html";

  /// .csv
  static const String csv = "text/csv";

  /// .json
  static const String json = "application/json";

  /// .jpg
  static const String jpeg = "image/jpeg";

  /// 所有图片
  static const String image = "image/*";

  /// .png
  static const String png = "image/png";

  /// .gif
  static const String gif = "image/gif";

  /// .webp
  static const String webp = "image/webp";

  /// .pdf
  static const String pdf = "application/pdf";

  /// .zip
  static const String zip = "application/zip";

  /// .rar
  static const String rar = "application/x-rar-compressed";

  /// .jar
  static const String jar = "application/java-archive";

  /// .xls
  static const String xls = "application/vnd.ms-excel";

  /// .xlsx
  static const String xlsx =
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

  /// .doc
  static const String doc = "application/msword";

  /// .docx
  static const String docx =
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document";

  /// .ppt
  static const String ppt = "application/mspowerpoint";

  /// .pptx
  static const String pptx =
      "application/vnd.openxmlformats-officedocument.presentationml.presentation";

  /// .mp3
  static const String mp3 = "audio/mpeg";

  /// .wav
  static const String wav = "audio/wav";

  /// .mp4
  static const String mp4 = "video/mp4";

  /// .apk
  static const String apk = "application/vnd.android.package-archive";

  /// 未知
  static const String unknown = "application/octet-stream";
}

abstract class StringRes {
  abstract String openDocument;
  abstract String lately;
  abstract String image;
  abstract String audio;
  abstract String video;
  abstract String download;
  abstract String rootFolder;
  abstract String document;
  abstract String zip;
  abstract String searchContent;
  abstract String noValidThirdAppForFilePreviewHint;
  abstract String filePreviewFailedHint;
  /// 文件选中格式化文本，如：已选择 1$d / 2$d
  abstract String fileChosenCountFormat;
  abstract String search;
  abstract String emptyData;
  abstract String sortType;
  abstract String showHideFile;
  abstract String notShowHideFile;
  abstract String sortFileNameAz;
  abstract String sortFileNameZa;
  abstract String sortFileTimeAsc;
  abstract String sortFileTimeDesc;
}
